package com.senmiao.ssm.config;

import com.senmiao.ssm.config.cache.RedisCacheManager;
import com.senmiao.ssm.constants.MyConstants;
import com.senmiao.ssm.realm.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    // 安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(getRealm());

        return defaultWebSecurityManager;
    }

    // 过滤器
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());
        Map<String, String> map = new LinkedHashMap<>();
        map.put("/admin/login","anon");
//        map.put("/admin/logout","anon");// 测试用
        map.put("/static/**","anon");
        map.put("/**","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setLoginUrl("/static/login.html");
        return shiroFilterFactoryBean;
    }

    // 自定义realm
    @Bean
    public Realm getRealm(){
        MyRealm myRealm = new MyRealm();
        // 设置密码匹配器
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashIterations(MyConstants.INTERATIONS);
        hashedCredentialsMatcher.setHashAlgorithmName(MyConstants.HASH_ALGORITHM);
        myRealm.setCredentialsMatcher(hashedCredentialsMatcher);

        // 设置realm的缓存管理器
        myRealm.setAuthorizationCachingEnabled(true);
        myRealm.setAuthenticationCachingEnabled(true);
        myRealm.setAuthenticationCacheName("AuthenticationCacheName");
        myRealm.setAuthorizationCacheName("AuthorizationCacheName");
        myRealm.setCacheManager(new RedisCacheManager());
        return myRealm;
    }

    // 生命周期执行流程
    @Bean
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        LifecycleBeanPostProcessor lifecycleBeanPostProcessor = new LifecycleBeanPostProcessor();
        return lifecycleBeanPostProcessor;
    }

    // aop增强
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        // 代理目标类
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    // 实现注解方式
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        // 依赖权限管理器
        authorizationAttributeSourceAdvisor.setSecurityManager(getDefaultWebSecurityManager());

        return authorizationAttributeSourceAdvisor;
    }

}
